package com.rzjm.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rzjm.api.dao.WxTemplateMapper;
import com.rzjm.api.entity.*;
import com.rzjm.api.service.*;
import com.rzjm.api.util.DateUtil;
import com.rzjm.api.util.MathUtil;
import com.rzjm.api.util.WxMessage;
import org.apache.coyote.ErrorState;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class WxTemplateServiceImpl extends BaseServiceImpl<WxTemplateMapper, WxTemplate> implements WxTemplateService {

    @Resource
    private UserMpService userMpService;
    @Resource
    private WxTemplateService wxTemplateService;
    @Resource
    protected RedisTemplate<String, Object> redisTemplate;
    @Resource
    private UserService userService;
    @Resource
    private ChargerService chargerService;
    @Resource
    private ParameterService parameterService;
    @Resource
    private ChargerManagerService chargerManagerService;
    @Resource
    private IDeviceWaterManagerService deviceWaterManagerService;
    @Resource
    private EstateService estateService;

    @Value("${web.appid}")
    private String appid;
    @Value("${web.appidMp}")
    private String appidMp;
    @Value("${web.secret}")
    private String secret;
    @Value("${web.secretMp}")
    private String secretMp;

    @Override
    public int sendWxMsgBeginCharger(User user, ChargerOrder chargerOrder) {
        try{
            String access_token = getAccessToken(0);
            //充电开始通知
            WxMsgTemplate template = getChargerTemplateToUser(user,chargerOrder,12);
            String param = JSONUtil.parseObj(template).toString();
            JSONObject jsonReturn = WxMessage.sendMsg(access_token,param);
            System.out.println("公众号推送消息 - 用户端响应信息:" + jsonReturn.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
        return 1;
    }

    /**
     *  开始充电 发给用户的推送消息
     * @param user
     * @param chargerOrder
     * @param template_type
     * @return
     */
    private WxMsgTemplate getChargerTemplateToUser(User user, ChargerOrder chargerOrder, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        UserMp userMp = userMpService.selectByUniqueColumn("union_id",user.getUnionId());
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

            Map<String,Object> miniprogram = new HashMap<>();
            miniprogram.put("appid",appid);
            miniprogram.put("pagepath","pagesDevice/pages/charger/orderList/index");
            template.setMiniprogram(miniprogram);

            Map<String, MsgTempData> m = new HashMap<>();
//            {{first.DATA}}
//            设备编号：{{keyword1.DATA}}
//            开始时间：{{keyword2.DATA}}
//            充电方案：{{keyword3.DATA}}
//            充电位置：{{keyword4.DATA}}
//            {{remark.DATA}}
            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            first.setValue("尊敬的用户您好，支付已成功，充电已开启。");
            m.put("first",first);

            //设备编号
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(chargerOrder.getDeviceSn());
            m.put("keyword1",keyword1);

            //开始时间
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            keyword2.setValue(DateUtil.getTime(new Date()));
            m.put("keyword2",keyword2);

            //充电方案
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue(chargerOrder.getBuyHour() + "小时");
            m.put("keyword3",keyword3);

            //充电位置
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getFontColor());
            keyword4.setValue(chargerOrder.getDeviceName());
            m.put("keyword4",keyword4);

            Charger charger = chargerService.findById(chargerOrder.getDeviceId());

            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            remark.setValue("尊敬的业主，您的爱车已经开始充电，由于电动车功率大小不同，充电时长以最终设备检测实际显示为准，，故障电话：" + charger.getManagerPhone());
            m.put("remark",remark);
            template.setData(m);
        }
        return template;
    }

    /**
     * 发送充电开始公众号推送消息
     * @param chargerOrder
     * @return
     */
    @Override
    public int sendWxMsgEndCharger(ChargerOrder chargerOrder) {
        User user = userService.findById(chargerOrder.getUserId());
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("order_id",chargerOrder.getId());
        jsonObject.set("user_id",user.getId());
        jsonObject.set("order","10");
        try {
            String access_token = getAccessToken(0);
            //充电结束通知
            WxMsgTemplate template = getEndChargerTemplateToUser(user,chargerOrder,13);
            String param = JSONUtil.parseObj(template).toString();
            JSONObject jsonReturn = WxMessage.sendMsg(access_token,param);
            System.out.println("公众号推送消息 - 用户端响应信息:" + jsonReturn.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }


    /**
     *  结束充电 发给用户的推送消息
     * @param user
     * @param chargerOrder
     * @param template_type
     * @return
     */
    private WxMsgTemplate getEndChargerTemplateToUser(User user, ChargerOrder chargerOrder, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        UserMp userMp = userMpService.selectByUniqueColumn("union_id",user.getUnionId());
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

            Map<String,Object> miniprogram = new HashMap<>();
            miniprogram.put("appid",appid);
            miniprogram.put("pagepath","pagesDevice/pages/charger/orderList/index");
            template.setMiniprogram(miniprogram);

            Charger charger = chargerService.findById(chargerOrder.getDeviceId());
            Map<String, MsgTempData> m = new HashMap<>();
//            {{first.DATA}}
//            充电地址：{{keyword1.DATA}}
//            结束时间：{{keyword2.DATA}}
//            消费金额：{{keyword3.DATA}}
//            退还金额：{{keyword4.DATA}}
//            账户余额：{{keyword5.DATA}}
//            {{remark.DATA}}
            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            first.setValue("尊敬的用户您好，充电已结束。");
            m.put("first",first);

            //充电地址
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(charger.getAddress());
            m.put("keyword1",keyword1);

            //结束时间
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            keyword2.setValue(DateUtil.getTime(new Date()));
            m.put("keyword2",keyword2);

            //消费金额
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            if(chargerOrder.getIsFree() == 0){
                keyword3.setValue(MathUtil.getDoubleUp(chargerOrder.getUsePrice().doubleValue()) + "元");
            }else{
                keyword3.setValue("0.00元");
            }
            m.put("keyword3",keyword3);

            double leftMoney = MathUtil.getDoubleUp(chargerOrder.getTotalPrice().doubleValue() - chargerOrder.getUsePrice().doubleValue());
            //退还金额
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getFontColor());

            if(chargerOrder.getIsFree() == 0) {
                keyword4.setValue(leftMoney + "元");
            }else{
                keyword4.setValue("0.00元");
            }
            m.put("keyword4",keyword4);


            //账户余额
            MsgTempData keyword5 = new MsgTempData();
            keyword5.setColor(wxTemplate.getFontColor());
            keyword5.setValue("0.00元");
            m.put("keyword5",keyword5);


            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            if(chargerOrder.getIsFree() == 0){
                if(leftMoney > 0){
                    remark.setValue("尊敬的业主，您的爱车充电已结束，由于电动车功率大小不同，充电时长以最终设备检测实际显示为准，剩余的余额已退回到您的微信账户，感谢您的使用。");
                }else{
                    remark.setValue("尊敬的业主，您的爱车充电已结束，由于电动车功率大小不同，充电时长以最终设备检测实际显示为准，感谢您的使用。");
                }
            }else{
                remark.setValue("尊敬的业主，您的爱车充电已结束，感谢您的免费使用。");
            }
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }


    @Override
    public int sendWxMsgOfflineCharger(Charger charger) {
        try {
            String access_token = getAccessToken(0);
            QueryWrapper<ChargerManager> qw = new QueryWrapper<>();
            qw.eq("charger_id",charger.getId());
            List<ChargerManager> managerList = chargerManagerService.list(qw);
            if(CollUtil.isNotEmpty(managerList)){
                for (ChargerManager manager : managerList){
                    //离线通知
                    WxMsgTemplate template = getOfflineChargerTemplateToManager(manager,charger,6);
                    String param = JSONUtil.parseObj(template).toString();
                    JSONObject jsonReturn = WxMessage.sendMsg(access_token,param);
                    System.out.println("公众号推送消息 - 用户端响应信息:" + jsonReturn.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }

    @Override
    public int sendWxMsgOfflineWater(DeviceWater water) {
        try {
            String access_token = getAccessToken(0);
            QueryWrapper<DeviceWaterManager> qw = new QueryWrapper<>();
            qw.eq("device_id",water.getId());
            List<DeviceWaterManager> managerList = deviceWaterManagerService.list(qw);
            if(CollUtil.isNotEmpty(managerList)){
                for (DeviceWaterManager manager : managerList){
                    //离线通知
                    WxMsgTemplate template = getOfflineDeviceWaterTemplateToManager(manager, water,6);
                    String param = JSONUtil.parseObj(template).toString();
                    JSONObject jsonReturn = WxMessage.sendMsg(access_token,param);
                    System.out.println("公众号推送消息 - 用户端响应信息:" + jsonReturn.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }

    /**
     *  充电设备离线后  发送推送消息到管理员身上
     * @param manager
     * @param template_type
     * @return
     */
    private WxMsgTemplate getOfflineChargerTemplateToManager(ChargerManager manager,Charger charger, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        UserMp userMp = userMpService.selectByUniqueColumn("union_id",manager.getUnionId());
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

//            Map<String,Object> miniprogram = new HashMap<>();
//            miniprogram.put("appid",appid);
//            miniprogram.put("pagepath","pagesDevice/pages/charger/orderList/index");
//            template.setMiniprogram(miniprogram);

            Map<String, MsgTempData> m = new HashMap<>();

//            {{first.DATA}}
//            小区：{{keyword1.DATA}}
//            设备：{{keyword2.DATA}}
//            原因：{{keyword3.DATA}}
//            时间：{{keyword4.DATA}}
//            {{remark.DATA}}

            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            first.setValue("充电设备离线预警，请尽快排查处理！");
            m.put("first",first);

            Estate estate = estateService.findById(charger.getEstateId());

            //小区
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(estate.getEstateName());
            m.put("keyword1",keyword1);

            //设备
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            keyword2.setValue("设备编号：" + charger.getChargerSn() + "");
            m.put("keyword2",keyword2);

            //原因
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue("设备已离线");
            m.put("keyword3",keyword3);

            //时间
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getFontColor());
            keyword4.setValue(DateUtil.getTime());
            m.put("keyword4",keyword4);

            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            remark.setValue("该设备已离线，请及时排查原因！");
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }



    /**
     *  充电设备离线后  发送推送消息到管理员身上
     * @param manager
     * @param template_type
     * @return
     */
    private WxMsgTemplate getOfflineDeviceWaterTemplateToManager(DeviceWaterManager manager,DeviceWater water, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        UserMp userMp = userMpService.selectByUniqueColumn("union_id", manager.getUnionId());
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

//            Map<String,Object> miniprogram = new HashMap<>();
//            miniprogram.put("appid",appid);
//            miniprogram.put("pagepath","pagesDevice/pages/charger/orderList/index");
//            template.setMiniprogram(miniprogram);

            Map<String, MsgTempData> m = new HashMap<>();

//            {{first.DATA}}
//            小区：{{keyword1.DATA}}
//            设备：{{keyword2.DATA}}
//            原因：{{keyword3.DATA}}
//            时间：{{keyword4.DATA}}
//            {{remark.DATA}}

            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            first.setValue("充电设备离线预警，请尽快排查处理！");
            m.put("first",first);

            Estate estate = estateService.findById(water.getEstateId());

            //小区
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            if(estate == null){
                keyword1.setValue("未绑定小区");
            }else{
                keyword1.setValue(estate.getEstateName());
            }
            m.put("keyword1",keyword1);

            //设备
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            keyword2.setValue("设备编号：" + water.getDeviceSn() + "");
            m.put("keyword2",keyword2);

            //原因
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue("设备已离线");
            m.put("keyword3",keyword3);

            //时间
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getFontColor());
            keyword4.setValue(DateUtil.getTime());
            m.put("keyword4",keyword4);

            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            remark.setValue("该设备已离线，请及时排查原因！");
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }


    @Override
    @Transactional
    public String getAccessToken(int type) {
        String access_token = "";
        try{
            Parameter parameter = parameterService.findById(1);
            if(type == 0){//公众号
                access_token = parameter.getAccessTokenMp();
                if(new Date().getTime() > parameter.getAcMpLastTime().getTime()){
                    access_token = WxMessage.getACCESSTOKEN(appidMp,secretMp);
                    parameter.setAccessTokenMp(access_token);
                    //记录2小时之后的时间
                    parameter.setAcMpLastTime(DateUtil.getAfterSecondsByOld(new Date(),7200));
                    parameterService.updateById(parameter);
                }
            }else{//小程序
                access_token = parameter.getAccessToken();
                if(new Date().getTime() > parameter.getAcLastTime().getTime()) {
                    access_token = WxMessage.getACCESSTOKEN(appid, secret);
                    parameter.setAccessToken(access_token);
                    parameter.setAcLastTime(DateUtil.getAfterSecondsByOld(new Date(),7200));
                    parameterService.updateById(parameter);
                }
            }
            parameterService.resetParameter(1);
        }catch (Exception e){
            e.printStackTrace();
        }
        return access_token;
    }

}
